package com.ourway.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.liuweiheng.base.utils.HttpUtil;
import com.ourway.constant.FeiShuConstants;
import com.ourway.dao.FeiShuUserSyncMapper;
import com.ourway.dao.UserMapper;
import com.ourway.dtos.*;
import com.ourway.entity.*;
import com.ourway.entity.vo.FeiShuNormalResponseVo;
import com.ourway.service.IDepartmentService;
import com.ourway.service.IFeiShuService;
import com.ourway.service.IUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 用户服务接口实现类
 *
 * @author liuweiheng
 * @since 2021/12/12
 */
@Service
public class UserServiceImpl implements IUserService {
    private final UserMapper userMapper;
    private final IFeiShuService feiShuService;
    private final FeiShuConstants feiShuConstants;
    private final IDepartmentService departmentService;
    private final FeiShuUserSyncMapper feiShuUserSyncMapper;

    public UserServiceImpl(UserMapper userMapper, IFeiShuService feiShuService, FeiShuConstants feiShuConstants, IDepartmentService departmentService, FeiShuUserSyncMapper feiShuUserSyncMapper) {
        this.userMapper = userMapper;
        this.feiShuService = feiShuService;
        this.feiShuConstants = feiShuConstants;
        this.departmentService = departmentService;
        this.feiShuUserSyncMapper = feiShuUserSyncMapper;
    }

    @Override
    public UserDTO getByUserId(String userId) {
        User entity = new LambdaQueryChainWrapper<>(userMapper).eq(User::getUserId, userId).one();
        if (null != entity) {
            UserDTO userDTO = new UserDTO();
            BeanUtils.copyProperties(entity, userDTO);
            return userDTO;
        }
        return null;
    }

    @Override
    public Boolean update(UserDTO userDTO) {
        User user = new User();
        userDTO.setUpdateTime(new Date(System.currentTimeMillis()));
        BeanUtils.copyProperties(userDTO, user);

        // 查询用户是否存在
        UserDTO old = getByUserId(userDTO.getUserId());
        Assert.notNull(old, "用户尚未在本系统注册");

        // 获取飞书映射ID
        FeiShuUserSync userSyncInfo = feiShuService.getUserSyncInfo(userDTO.getUserId());
        Assert.notNull(userSyncInfo, "用户未同步到飞书");

        // 查询飞书是否存在对象
        FeiShuUser feiShuUser = feiShuService.getFeiShuUser(userSyncInfo.getFeishuOpenId());
        Assert.notNull(feiShuUser, "用户在飞书未存在");

        FeiShuUserUpdateDTO oldFeiShuUser = FeiShuUserUpdateDTO.builder().build();
        BeanUtils.copyProperties(feiShuUser.getUser(), oldFeiShuUser);

        // 封装部门同步信息
        FeiShuDepartmentSync deptSyncInfo = departmentService.getSyncInfoByDeptId(userDTO.getDepartmentId());
        userDTO.setDepartmentSyncId(deptSyncInfo.getFeishuOpenDepartmentId());

        // 封装领导同步信息
        if (StrUtil.isNotBlank(userDTO.getManagerId())) {
            FeiShuUserSync leaderSyncInfo = feiShuService.getUserSyncInfo(userDTO.getManagerId());
            Assert.notNull(leaderSyncInfo, "上级领导尚未同步至飞书");
            userDTO.setManagerSyncId(leaderSyncInfo.getFeishuOpenId());
        }

        // 设置未更新的属性为null
        FeiShuUserUpdateDTO newFeiShuUser = FeiShuUserUpdateDTO.userDto2FeiShuUserUpdateDto(userDTO);
        newFeiShuUser.setNoneUpdatePropertyNull(oldFeiShuUser);

        // 更新飞书
        String url = feiShuConstants.getUpdateUserUrl(userSyncInfo.getFeishuOpenId());
        String accessToken = feiShuService.getTenantAccessToken();
        Map<String, String> header = new HashMap<>(1);
        header.put("Authorization", "Bearer " + accessToken);
        String response = HttpUtil.patchWithJsonSync(url, newFeiShuUser, String.class, header);

        FeiShuNormalResponseVo responseVo = JSONUtil.toBean(response, FeiShuNormalResponseVo.class);

        boolean result = responseVo.getCode() == 0;

        Assert.isTrue(result, "同步更新飞书失败");

        // 更新数据库
        int updateCount = userMapper.updateById(user);
        if (updateCount == 0) {
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }

    @Transactional
    @Override
    public Boolean create(UserDTO userDTO) {
        User user = new User();
        Date now = new Date(System.currentTimeMillis());
        userDTO.setCreateTime(now)
                .setUpdateTime(now)
                .setUserId(StrUtil.uuid().replaceAll("-", ""))
                .setDeleteFlag(0);
        BeanUtils.copyProperties(userDTO, user);

        // 获取部门同步信息
        FeiShuDepartmentSync deptSyncInfo = departmentService.getSyncInfoByDeptId(userDTO.getDepartmentId());
        Assert.notNull(deptSyncInfo, "上级部门未同步至飞书");

        // 查询数据库是否存在该部门
        DepartmentDTO dbDept = departmentService.getByDeptId(deptSyncInfo.getDepartmentId());

        Assert.notNull(dbDept, "上级部门在本系统中不存在");

        // 查询飞书是否存在该部门
        FeiShuDepartment feishuDept = departmentService.getFeiShuDeptByOpenDeptId(deptSyncInfo.getFeishuOpenDepartmentId());
        Assert.notNull(feishuDept, "上级部门尚未同步到飞书");

        // 封装部门同步信息
        userDTO.setDepartmentSyncId(deptSyncInfo.getFeishuOpenDepartmentId());

        // 获取并封装领导同步信息
        if (StrUtil.isNotBlank(userDTO.getManagerId())) {
            FeiShuUserSync leaderSyncInfo = feiShuService.getUserSyncInfo(userDTO.getManagerId());
            Assert.notNull(leaderSyncInfo, "上级领导尚未同步至飞书");
            userDTO.setManagerSyncId(leaderSyncInfo.getFeishuOpenId());
        }

        FeiShuUserAddDTO feiShuUserAddDTO = FeiShuUserAddDTO.userDto2FeiShuUserAddDto(userDTO);

        // 同步用户到飞书
        FeiShuUser newObj = feiShuService.createFeiShuUser(feiShuUserAddDTO);

        Assert.notNull(newObj, "同步至飞书失败");

        // 同步到数据库
        int count = userMapper.insert(user);

        if (count == 0) {
            return Boolean.FALSE;
        }

        // 封装同步信息
        FeiShuUserSync feiShuUserSync = new FeiShuUserSync()
                .setUserId(userDTO.getUserId())
                .setFeishuUserId(newObj.getUser().getUserId())
                .setFeishuOpenId(newObj.getUser().getOpenId())
                .setFeishuUnionId(newObj.getUser().getUnionId())
                .setCreateTime(now)
                .setUpdateTime(now);
        int count2 = feiShuUserSyncMapper.insert(feiShuUserSync);

        if (count2 == 0) {
            return Boolean.FALSE;
        }

        return Boolean.TRUE;
    }

    @Override
    public boolean delete(UserDTO userDTO) {
        // 检查用户是否存在
        UserDTO old = getByUserId(userDTO.getUserId());
        Assert.notNull(old, "用户尚未在本系统注册");

        // 检查用户是否在飞书注册
        // 获取飞书映射ID
        FeiShuUserSync userSyncInfo = feiShuService.getUserSyncInfo(userDTO.getUserId());
        Assert.notNull(userSyncInfo, "用户未同步到飞书");

        // 查询飞书是否存在对象
        FeiShuUser feiShuUser = feiShuService.getFeiShuUser(userSyncInfo.getFeishuOpenId());
        Assert.notNull(feiShuUser, "用户在飞书中未注册");

        FeiShuUserDeleteDTO userDeleteDTO = null;

        // 封装对接人信息
        if (StrUtil.isNotBlank(userDTO.getAcceptorUserId())) {
            CheckUserResultDTO checkResult = checkUserIsExist(userDTO.getAcceptorUserId());
            if (checkResult.hasError) {
                throw new IllegalArgumentException(checkResult.getMessage());
            }
            userDeleteDTO = FeiShuUserDeleteDTO.init(userSyncInfo.getFeishuOpenId(), checkResult.getFeiShuUserSync().getFeishuOpenId());
        } else {
            userDeleteDTO = FeiShuUserDeleteDTO.builder().userId(userSyncInfo.getFeishuOpenId()).build();
        }

        boolean successFlag = feiShuService.deleteUser(userDeleteDTO);
        Assert.isTrue(successFlag, "同步至飞书失败");

        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserId, userDTO.getUserId());
        int count = userMapper.delete(queryWrapper);

        if (count == 0) {
            return Boolean.FALSE;
        }

        LambdaQueryWrapper<FeiShuUserSync> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FeiShuUserSync::getUserId, userDTO.getUserId());
        int count2 = feiShuUserSyncMapper.delete(wrapper);

        if (count2 == 0) {
            return Boolean.FALSE;
        }

        return Boolean.TRUE;
    }

    private CheckUserResultDTO checkUserIsExist(String userId) {
        // 检查用户是否存在
        UserDTO old = getByUserId(userId);
        if (null == old) {
            return CheckUserResultDTO.error("用户尚未在本系统注册");
        }


        // 检查用户是否在飞书注册
        // 获取飞书映射ID
        FeiShuUserSync userSyncInfo = feiShuService.getUserSyncInfo(userId);
        if (null == userSyncInfo) {
            return CheckUserResultDTO.error("用户未同步到飞书");
        }

        // 查询飞书是否存在对象
        FeiShuUser feiShuUser = feiShuService.getFeiShuUser(userSyncInfo.getFeishuOpenId());
        if (null == feiShuUser) {
            return CheckUserResultDTO.error("用户在飞书中未注册");
        }

        return CheckUserResultDTO.success(null, old, userSyncInfo, feiShuUser);
    }
}
